
#include <treeview_filter.h>

FILTROPACOTE::FILTROPACOTE() {
    this->add(this->Interface);
    this->add(this->origem);
    this->add(this->portaOrigem);
    this->add(this->destino);
    this->add(this->portaDestino);
    this->add(this->protocolo);
    this->add(this->quantidade);
    this->add(this->visible);
}

/*
 * Método construtor que rotulo nas colunas da treeview
 */
treeview_filter::treeview_filter() {
    this->rowselect.clear();

    this->pt_filtro = Gtk::ListStore::create(this->filtro);
    this->pt_filtro->clear();

    this->remove_all_columns();
    this->append_column(Glib::ustring("Interface"), this->filtro.Interface);
    this->append_column(Glib::ustring("Origem"), this->filtro.origem);
    this->append_column(Glib::ustring("Porta Origem"), this->filtro.portaOrigem);
    this->append_column(Glib::ustring("Destino"), this->filtro.destino);
    this->append_column(Glib::ustring("Porta Destino"), this->filtro.portaDestino);
    this->append_column(Glib::ustring("Protocolo"), this->filtro.protocolo);
    this->append_column(Glib::ustring("Quantidade"), this->filtro.quantidade);

    this->treemodelfilter = Gtk::TreeModelFilter::create(this->pt_filtro);

    /* método que será usado para filtragem das linhas */
    this->treemodelfilter->set_visible_func(sigc::mem_fun(*this, &treeview_filter::order_row_visible));
    this->set_model(this->treemodelfilter);
}

/*
 * Método que adiciona conteudo a treeview
 */
void treeview_filter::content_filter() {
    int cont;
    string sql;
    struct hostent *he;
    struct in_addr addr;
    banco *bd;
    vector<vector<string> >::iterator i; //interador para buscar no BD
    vector<string> valor; //recebe conteudo

    this->pt_filtro->clear();

    bd = new banco(FILE_DB_FILTER);

    sql = "SELECT rf_interface, rf_origem,";
    sql += " CASE WHEN rf_origem_porta = 0 THEN NULL ELSE rf_origem_porta END,";
    sql += " rf_destino,";
    sql += " CASE WHEN rf_destino_porta = 0 THEN NULL ELSE rf_destino_porta END,";
    sql += " rf_protocolo, rf_quantidade";
    sql += " FROM resumo_filtro ORDER BY rf_quantidade DESC, rf_origem, rf_destino";


    bd->query(sql.c_str());

    if (bd->getStatus()) {
        /* atribui os valores BD */
        for (i = bd->resultados.begin(); i < bd->resultados.end(); i++) {
            valor = *i;

            this->row = *(this->pt_filtro->append());

            for (cont = 0; cont < 7; cont++) {

                sql = valor.at(cont);

                if ((cont == 0)) {
                    this->row[this->filtro.Interface] = sql;
                } else if ((cont == 1)) {

                    /* converte endereço ip em dns
                    if ((he = gethostbyname(value))) {
                        sql.clear();
                        sql.append(he->h_name);
                    }
                     *  */

                    this->row[this->filtro.origem] = sql;
                } else if ((cont == 2)) {
                    this->row[this->filtro.portaOrigem] = sql;
                } else if ((cont == 3)) {
                    /* converte endereço ip em dns
                    if ((he = gethostbyname(value))) {
                        sql.clear();
                        sql.append(he->h_name);
                    }
                     */

                    this->row[this->filtro.destino] = sql;
                } else if ((cont == 4)) {
                    this->row[this->filtro.portaDestino] = sql;
                } else if ((cont == 5)) {
                    this->row[this->filtro.protocolo] = sql;
                } else if ((cont == 6)) {
                    this->row[this->filtro.quantidade] = sql;
                }
            }

            this->row[this->filtro.visible] = true;
        }
    }

    delete bd;
}

/*
 * Método que deleta o conteudo da treeview
 * Retorna true caso tenha excluido com sucesso
 */
bool treeview_filter::delete_row() {
    string sql;
    banco *bd;

    bd = new banco(FILE_DB_FILTER);

    sql = "DELETE FROM pacotes_filtro";
    bd->query(sql.c_str());

    sql = "DELETE FROM resumo_filtro";
    bd->query(sql.c_str());

    delete bd;

    this->pt_filtro->clear();
}

/*
 * Método que retorna dados da linha selecionada
 * Retorna uma string com os dados
 */
string treeview_filter::create_by_row() {
    Glib::RefPtr<Gtk::TreeSelection> Linha_sel = this->get_selection(); //ponteiro para linha selecionada da treeview
    Gtk::TreeModel::iterator iter = Linha_sel->get_selected(); //recebe linha selecionada
    string retorno, aux;

    if (Linha_sel->count_selected_rows()) {
        Gtk::TreeModel::Row row = *iter;

        retorno.clear();
        aux.clear();

        retorno = "<interface>";
        aux = row[this->filtro.Interface];
        retorno += aux + "</interface><origem>";
        aux = row[this->filtro.origem];
        retorno += aux + "</origem><portOrigem>";
        aux = row[this->filtro.portaOrigem];
        retorno += aux + "</portOrigem><destino>";
        aux = row[this->filtro.destino];
        retorno += aux + "</destino><portDestino>";
        aux = row[this->filtro.portaDestino];
        retorno += aux + "</portDestino><protocolo>";
        aux = row[this->filtro.protocolo];
        retorno += aux + "</protocolo>";

        return retorno;
    } else {
        /* caso o usuário tente excluir sem selecionar uma linha informa um erro */
        return "Selecione uma linha.";
    }
}

/*
 * Método que solicita a filtragem de dados na treeview
 * a partir de uma linha selecionada e qual coluna de referencia
 * str Nome da coluna de referencia
 */
void treeview_filter::reorder_row(string str) {
    Glib::RefPtr<Gtk::TreeSelection> Linha_sel = this->get_selection(); //ponteiro para linha selecionada da treeview
    Gtk::TreeModel::iterator iter = Linha_sel->get_selected(); //recebe linha selecionada

    if (Linha_sel->count_selected_rows()) {
        Gtk::TreeModel::Row row = *iter;

        this->column = str;

        if (str == "Origem") {
            this->rowselect = row[this->filtro.origem];
        } else if (str == "Porta Origem") {
            this->rowselect = row[this->filtro.portaOrigem];
        } else if (str == "Destino") {
            this->rowselect = row[this->filtro.destino];
        } else if (str == "Porta Destino") {
            this->rowselect = row[this->filtro.portaDestino];
        } else if (str == "Protocolo") {
            this->rowselect = row[this->filtro.protocolo];
        } else {
            this->column.clear();
            this->rowselect.clear();
        }
    }

    this->treemodelfilter->refilter();
}

/*
 * Método que reordena os dados da treeview
 * iter "Ponteiro" para linha
 * retorna true se a linha será exibida ou false caso contrario.
 */
bool treeview_filter::order_row_visible(const Gtk::TreeModel::const_iterator& iter) {
    /* se não tiver nenhum regra de filtragem mostra todas */
    if (this->rowselect.empty() || this->column.empty()) {
        Gtk::TreeModel::Row row = *iter;
        return row[this->filtro.visible];
    } else if (iter) {
        /* filtra segundo os dados de uma coluna */
        Gtk::TreeModel::Row row = *iter;
        string aux;

        if (this->column == "Origem") {
            aux = row[this->filtro.origem];
        } else if (this->column == "Porta Origem") {
            aux = row[this->filtro.portaOrigem];
        } else if (this->column == "Destino") {
            aux = row[this->filtro.destino];
        } else if (this->column == "Porta Destino") {
            aux = row[this->filtro.portaDestino];
        } else if (this->column == "Protocolo") {
            aux = row[this->filtro.protocolo];
        } else {
            aux.clear();
        }

        return ((aux == this->rowselect) && (row[this->filtro.visible]));
    }

    return true;
}
